package com.tree.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tree.backend.common.Result;
import com.tree.backend.entity.dto.CustomerDemandDTO;
import com.tree.backend.entity.pojo.*;
import com.tree.backend.entity.vo.CustomerDemandVO;
import com.tree.backend.mapper.*;
import com.tree.backend.service.ICustomerDemandService;
import com.tree.backend.utils.DataMappingUtils;
import com.tree.backend.utils.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@RequiredArgsConstructor
public class CustomerDemandServiceImpl extends ServiceImpl<CustomerDemandMapper, CustomerDemand> implements ICustomerDemandService {

    private final PowerZoneMapper powerZoneMapper;
    private final CompanyMapper companyMapper;
    private final PowerEquipmentMapper powerEquipmentMapper;
    private final CustomerMapper customerMapper;
    private final Random random = new Random();

    @Override
    public Result<Page<CustomerDemandVO>> getList(CustomerDemandDTO customerDemandDTO) {
        // 1. 创建区域映射map
        final Map<Integer, String> powerZoneNameMap = new HashMap<>();
        Page<CustomerDemand> customerDemandPage = new Page<>(customerDemandDTO.getPage(), customerDemandDTO.getPageSize());
        LambdaQueryWrapper<CustomerDemand> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        DataMappingUtils.applyPermissionFilter(
                () -> UserContext.getCompanyId() != 0,
                () -> powerZoneMapper.selectList(
                        new LambdaQueryWrapper<PowerZone>()
                                .eq(PowerZone::getCompanyId, UserContext.getCompanyId())),
                // 使用类型转换函数确保类型匹配
                PowerZone::getId,
                PowerZone::getZoneName,
                powerZoneNameMap,
                lambdaQueryWrapper,
                CustomerDemand::getPowerZoneId);


        // 3. 添加其他查询条件
        lambdaQueryWrapper
                .like(StringUtils.isNotBlank(customerDemandDTO.getDemandCode()), CustomerDemand::getDemandCode, customerDemandDTO.getDemandCode())
                .eq(customerDemandDTO.getDemandType() != null, CustomerDemand::getDemandType, customerDemandDTO.getDemandType())
                .like(StringUtils.isNotBlank(customerDemandDTO.getTitle()), CustomerDemand::getTitle, customerDemandDTO.getTitle())
                .like(StringUtils.isNotBlank(customerDemandDTO.getDescription()), CustomerDemand::getDescription, customerDemandDTO.getDescription())
                .eq(customerDemandDTO.getUrgencyLevel() != null, CustomerDemand::getUrgencyLevel, customerDemandDTO.getUrgencyLevel())
                .eq(customerDemandDTO.getDemandStatus() != null, CustomerDemand::getDemandStatus, customerDemandDTO.getDemandStatus());


        Page<CustomerDemand> page = page(customerDemandPage, lambdaQueryWrapper);
        if (page.getRecords().isEmpty()) return Result.success(new Page<>());


        // 区域填充
        DataMappingUtils.buildIdNameMap(
                page.getRecords(),
                CustomerDemand::getPowerZoneId,
                powerZoneMapper::selectByIds,
                PowerZone::getId,
                PowerZone::getZoneName,
                powerZoneNameMap
        );
        List<CustomerDemandVO> customerDemandVOList = DataMappingUtils.convertAndFillNames(
                page.getRecords(),
                CustomerDemandVO.class,
                CustomerDemand::getPowerZoneId,
                powerZoneNameMap,
                CustomerDemandVO::setZoneName,
                null
        );


        // 使用通用方法填充企业信息
        customerDemandVOList = fillNameMap(page.getRecords(),
                CustomerDemand::getCompanyId,
                companyMapper::selectByIds,
                Company::getId,
                Company::getCompanyName,
                CustomerDemandVO::setCompanyName,
                customerDemandVOList);

        // 使用通用方法填充客户信息
        customerDemandVOList = fillNameMap(page.getRecords(),
                CustomerDemand::getCustomerId,
                customerMapper::selectByIds,
                Customer::getId,
                Customer::getCustomerName,
                CustomerDemandVO::setCustomerName,
                customerDemandVOList);

        // 使用通用方法填充电力设备信息
        customerDemandVOList = fillNameMap(page.getRecords(),
                CustomerDemand::getEquipmentId,
                powerEquipmentMapper::selectByIds,
                PowerEquipment::getId,
                PowerEquipment::getEquipmentName,
                CustomerDemandVO::setEquipmentName,
                customerDemandVOList);

        Page<CustomerDemandVO> customerDemandVOPage = new Page<>();
        BeanUtils.copyProperties(page, customerDemandVOPage);
        customerDemandVOPage.setRecords(customerDemandVOList);
        return Result.success(customerDemandVOPage);
    }

    /**
     * 通用的名称映射和填充方法
     */
    private <T, K, D> List<CustomerDemandVO> fillNameMap(List<T> records,
                                                         java.util.function.Function<T, K> idExtractor,
                                                         java.util.function.Function<Collection<K>, List<D>> dataProvider,
                                                         java.util.function.Function<D, K> idMapper,
                                                         java.util.function.Function<D, String> nameMapper,
                                                         DataMappingUtils.BiConsumer<CustomerDemandVO, String> voSetFunction,
                                                         List<CustomerDemandVO> voList) {
        final Map<K, String> existingMap = new HashMap<>();
        DataMappingUtils.buildIdNameMap(
                records,
                idExtractor,
                dataProvider,
                idMapper,
                nameMapper,
                existingMap
        );
        return DataMappingUtils.convertAndFillNames(
                records,
                CustomerDemandVO.class,
                idExtractor,
                existingMap,
                voSetFunction,
                voList
        );
    }

    @Override
    public Result<Boolean> updateCustomerDemand(CustomerDemandDTO customerDemandDTO) {
        // 直接转换
        CustomerDemand customerDemand = new CustomerDemand();
        BeanUtils.copyProperties(customerDemandDTO, customerDemand);
        return Result.success(this.updateById(customerDemand));
    }

    @Override
    public Result<Boolean> batchAddWithRandomData(List<CustomerDemandDTO> customerDemandDTOList) {
        // 获取当前企业ID
        Integer companyId = UserContext.getCompanyId();

        // 转换为实体列表并随机填充相关ID和状态
        List<CustomerDemand> customerDemandList = new ArrayList<>();
        for (CustomerDemandDTO dto : customerDemandDTOList) {
            CustomerDemand customerDemand = new CustomerDemand();
            BeanUtils.copyProperties(dto, customerDemand);
            customerDemand.setCompanyId(companyId);

            // 随机填充需求类型 (0, 1, 2)
            if (dto.getDemandType() == null) {
                customerDemand.setDemandType(random.nextInt(3)); // 0, 1, 2
            }

            // 随机填充紧急程度 (0, 1, 2)
            if (dto.getUrgencyLevel() == null) {
                customerDemand.setUrgencyLevel(random.nextInt(3)); // 0, 1, 2
            }

            // 随机填充需求状态 (0, 1)
            if (dto.getDemandStatus() == null) {
                customerDemand.setDemandStatus(random.nextInt(2)); // 0, 1
            }

            // 先查询当前企业的电力区域ID列表
            List<Integer> powerZoneIds = powerZoneMapper.selectList(
                            new LambdaQueryWrapper<PowerZone>().select(PowerZone::getId)
                                    .eq(PowerZone::getCompanyId, companyId)).stream()
                    .map(PowerZone::getId).toList();

            // 优先填充区域ID
            if (!powerZoneIds.isEmpty()) {
                Integer selectedPowerZoneId = powerZoneIds.get(random.nextInt(powerZoneIds.size()));
                customerDemand.setPowerZoneId(selectedPowerZoneId);

                // 基于区域ID查询对应的客户ID列表
                List<Integer> customerIds = customerMapper.selectList(
                                new LambdaQueryWrapper<Customer>().select(Customer::getId)
                                        .in(Customer::getPowerZoneId, powerZoneIds)).stream()
                        .map(Customer::getId).toList();

                // 基于区域ID查询对应的设备ID列表
                List<Integer> equipmentIds = powerEquipmentMapper.selectList(
                                new LambdaQueryWrapper<PowerEquipment>().select(PowerEquipment::getId)
                                        .in(PowerEquipment::getPowerZoneId, powerZoneIds)).stream()

                        .map(PowerEquipment::getId).toList();

                // 随机填充客户ID（如果有数据的话）
                if (!customerIds.isEmpty()) {
                    customerDemand.setCustomerId(customerIds.get(random.nextInt(customerIds.size())));
                }

                // 随机填充设备ID（如果有数据的话）
                if (!equipmentIds.isEmpty()) {
                    // 80%概率设置设备ID
                    if (random.nextDouble() < 0.8) {
                        customerDemand.setEquipmentId(equipmentIds.get(random.nextInt(equipmentIds.size())));
                    }
                }
            }

            customerDemandList.add(customerDemand);
        }

        // 批量保存
        return Result.success(this.saveBatch(customerDemandList));
    }
}
